#include "StdAfx.h"
#include "HideModule.h"
#include "winternl.h"
#include "HookVirtualQuery.h"

typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
//PROCNTQSIP NtQueryInformationProcess;
typedef ULONG smPPS_POST_PROCESS_INIT_ROUTINE;

typedef struct _smRTL_USER_PROCESS_PARAMETERS {
	BYTE Reserved1[16];
	PVOID Reserved2[10];
	UNICODE_STRING ImagePathName;
	UNICODE_STRING CommandLine;
} smRTL_USER_PROCESS_PARAMETERS, *smPRTL_USER_PROCESS_PARAMETERS;

typedef struct __LDR_DATA_TABLE_ENTRY 
{
	ULONG Length;
	BOOL Initialsize;
	PVOID SsHandle;
	LIST_ENTRY InLoadOrderLinks;
	LIST_ENTRY InMemoryOrderModuleList;
	LIST_ENTRY InInitializationOrderModuleList;
	PVOID DllBase;
	PVOID EntryPoint;
	ULONG SizeOfImage;
	UNICODE_STRING FullDllName;
	UNICODE_STRING BaseDllName;
	ULONG Flags;
	USHORT LoadCount;
	USHORT TlsIndex;
	union
	{
		LIST_ENTRY HashLinks;
		PVOID SectionPointer;
	};
	ULONG CheckSum;
	union
	{
		ULONG TimeDateStamp;
		PVOID LoadedImports;
	};
	PVOID EntryPointActivationContext;
	PVOID PatchInformation;
	//BYTE Reserved1[8];
	//PVOID Reserved2[3];
	//LIST_ENTRY InMemoryOrderModuleList;
} LDR_DATA_TABLE_ENTRY1, 
*PLDR_DATA_TABLE_ENTRY1;

typedef struct _smPEB {
	BYTE Reserved1[2];
	BYTE BeingDebugged;
	BYTE Reserved2[1];
	PVOID Reserved3[2];
	PLDR_DATA_TABLE_ENTRY1 Ldr;
	smPRTL_USER_PROCESS_PARAMETERS ProcessParameters;
	BYTE Reserved4[104];
	PVOID Reserved5[52];
	smPPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
	BYTE Reserved6[128];
	PVOID Reserved7[1];
	ULONG SessionId;
} smPEB, *smPPEB;

CHideModule::CHideModule(void)
{
}

CHideModule::~CHideModule(void)
{
}

LIST_ENTRY* CHideModule::m_plistModule;
LIST_ENTRY  CHideModule::m_listModule;
HANDLE g_fuck;
WCHAR g_ModulePath[256] = {0};
CHookVirtualQuery g_ooHook;

BOOL CHideModule::HideMySelf()
{
	HMODULE hMod = GetModuleHandle( _T( "ntdll.dll"));
	HMODULE hModMyself = 0;//GetModuleHandle( _T("Melete.dll"));
	::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,(LPCWSTR)&g_fuck, &hModMyself);
	
	::GetModuleFileName(hModMyself, g_ModulePath, 255);
    //return 1;
#ifdef _DEBUG
	//return 1;
#endif
	DWORD dwOffset = (DWORD)hModMyself;
	DWORD dd=0;
	::ReadProcessMemory(GetCurrentProcess(), (LPVOID)(dwOffset+0x3c), &dwOffset, 4, &dd);
	dwOffset = dwOffset+(DWORD)hModMyself+0x50;
	::ReadProcessMemory(GetCurrentProcess(), (LPVOID)(dwOffset), &dwOffset,4,&dd);
	//g_ooHook.HookOn((HINSTANCE)hModMyself, dwOffset);
	
	PROCNTQSIP  p = NULL;
	p = ( PROCNTQSIP )::GetProcAddress( hMod, "NtQueryInformationProcess");

	PROCESS_BASIC_INFORMATION stInfo = {0};
	DWORD dwRetnLen = 0;
	DWORD dw = p( GetCurrentProcess(), 0, &stInfo, sizeof(stInfo), &dwRetnLen);

	PPEB pPeb = stInfo.PebBaseAddress;
	PLIST_ENTRY ListHead, Current;
	PLDR_DATA_TABLE_ENTRY1 pstEntry = NULL;
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//void*myPeb = NULL,
	//	*Ldr = NULL,
	//	*Flink = NULL,
	//	*p1 = NULL,
	//	*BaseAddress = NULL,
	//	*FullDllName = NULL;
	//__asm
	//{
	//	mov eax,fs:[0x30]
	//	mov myPeb,eax
	//}
	//Ldr = *( ( void ** )( ( unsigned char * )myPeb+0x0c ) );
	//Flink = *( ( void ** )( ( unsigned char * )Ldr+ 0x0c ) );
	//p1 = Flink;
	//WCHAR chwName[256] = {0};
	//do
	//{
	//	BaseAddress = *( ( void ** )( ( unsigned char * )p1+ 0x18 ) );
	//	FullDllName = *( ( void ** )( ( unsigned char * )p1+ 0x28 ) );
	//	wprintf(chwName, L"FullDllName is %s\n",FullDllName);
	//	printf("BaseAddress is %x\n",BaseAddress);
	//	p1 = *( ( void ** )p1);
	//}
	//while ( Flink != p1 );
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


	smPEB smoPEB = {0};
	LDR_DATA_TABLE_ENTRY1 ldroTable = {0};
	DWORD dwBytesRead = 0;
	if(pPeb)
	{
		if (ReadProcessMemory(GetCurrentProcess(), pPeb, &smoPEB, sizeof(smoPEB), &dwBytesRead))
			NULL;
	}
	ListHead = &( smoPEB.Ldr->InLoadOrderLinks);
	Current = ListHead->Flink;
	while ( Current != ListHead )
	{
		pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY1, InLoadOrderLinks);
		//	//DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);
		if ( pstEntry->DllBase == hModMyself)
		{
            m_plistModule = &(pstEntry->InLoadOrderLinks);
            m_listModule = pstEntry->InLoadOrderLinks;
			pstEntry->InLoadOrderLinks.Flink->Blink = pstEntry->InLoadOrderLinks.Blink;
			pstEntry->InLoadOrderLinks.Blink->Flink = pstEntry->InLoadOrderLinks.Flink;
			//		//DebugOut( _T( "Hide injected dll."));
			break;
		}
		Current = pstEntry->InLoadOrderLinks.Flink;
	}

	ListHead = &( smoPEB.Ldr->InMemoryOrderModuleList);
	Current = ListHead->Flink;
	while ( Current != ListHead)
	{
		pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY1, InMemoryOrderModuleList);
		//DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);
		if ( pstEntry->DllBase == hModMyself)
		{
			pstEntry->InMemoryOrderModuleList.Flink->Blink = pstEntry->InMemoryOrderModuleList.Blink;
			pstEntry->InMemoryOrderModuleList.Blink->Flink = pstEntry->InMemoryOrderModuleList.Flink;
			//DebugOut( _T( "Hide injected dll."));
			break;
		}
		Current = pstEntry->InMemoryOrderModuleList.Flink;
	}
	//DebugOutW( L"\r\n");

	ListHead = &( smoPEB.Ldr->InInitializationOrderModuleList);
	Current = ListHead->Flink;
	while ( Current != ListHead)
	{
		pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY1, InInitializationOrderModuleList);
		//DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);
		if ( pstEntry->DllBase == hModMyself)
		{
			pstEntry->InInitializationOrderModuleList.Flink->Blink = pstEntry->InInitializationOrderModuleList.Blink;
			pstEntry->InInitializationOrderModuleList.Blink->Flink = pstEntry->InInitializationOrderModuleList.Flink;
			//DebugOut( _T( "Hide injected dll."));
			break;
		}
		Current = pstEntry->InInitializationOrderModuleList.Flink;
	}

	DWORD dwPeBase = (DWORD)hModMyself;
	DWORD dwTemp,dwSize = 0;
	if (!dwPeBase || !VirtualProtect((LPVOID)dwPeBase, 0x1000 , PAGE_EXECUTE_READWRITE, &dwTemp))
	{
		return 0;
	}
	//WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwPeBase, 0, 0x1000, &dwSize);
	memset((LPVOID)dwPeBase, 0, 0x1000);
	return 1;

}

BOOL CHideModule::RemoveThemidia()
{
	DWORD hWOW = NULL;
	hWOW = (DWORD)::GetModuleHandle(NULL);
	DWORD dwTemp = 0;
	if (!hWOW || !VirtualProtect((LPVOID)hWOW, 2 , PAGE_EXECUTE_READWRITE,&dwTemp))
	{
		return 0;
	}


	WORD wDD = 0xffff;
	DWORD dwNum = 0;

	hWOW=hWOW+0x0C;
	WriteProcessMemory(GetCurrentProcess(), (LPVOID)hWOW, &wDD, 2, &dwNum); 
	VirtualProtect((LPVOID)hWOW, 2 , dwTemp,&dwNum);


	return 1;
}

void CHideModule::RemoveHook()
{
    if (m_plistModule)
    {
        *m_plistModule = m_listModule;
    }
	//g_ooHook.HookOff();
}